package com.vains.io;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.util.Assert;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.*;

/**
 * <p>
 *  HttpClient帮助类
 * </p>
 *
 * @author vains
 * @since 2020-07-06
 */
@Slf4j
public class HttpUtils {

    private HttpUtils() {}

    private static final CloseableHttpClient HTTP_CLIENT = HttpClients.createDefault();

    /**
     * 发送GET请求, 可以设置请求头,添加参数
     * @param url 请求地址
     * @param headers 请求头
     * @param params 请求参数
     * @return 返回响应结果,请求失败时返回null
     */
    public static String doGet(String url, Map<String, Object> headers, Map<String, Object> params) {
        Assert.hasLength(url, "请求地址不能为null！");
        try {
            // 声明URIBuilder
            URIBuilder uriBuilder = new URIBuilder(url);
            // 判断参数是否为空
            if (CollectionUtils.isNotEmpty(params)) {
                for (Map.Entry<String, Object> entry : params.entrySet()) {
                    // 添加参数
                    uriBuilder.setParameter(entry.getKey(), (String) entry.getValue());
                }
            }
            // 创建httpGet对象，相当于设置url请求地址
            HttpGet httpGet = new HttpGet(uriBuilder.build());
            // 判断请求头是否为空
            if (CollectionUtils.isNotEmpty(headers)) {
                for (Map.Entry<String, Object> entry : headers.entrySet()) {
                    // 添加请求头
                    httpGet.addHeader(entry.getKey(), (String) entry.getValue());
                }
            }
            return executeHttp(httpGet);
        } catch (URISyntaxException e) {
            log.error("url转义失败,原因: ", e);
        }
        return null;
    }

    /**
     * get请求,带参数,默认请求头
     * @param url 请求地址
     * @param params 请求参数
     * @return 返回请求结果
     */
    public static String doGet(String url, Map<String, Object> params) {
        return doGet(url, null, params);
    }

    /**
     * get请求不带参数
     * @param url 请求地址
     * @return 返回请求结果
     */
    public static String doGet(String url) {
        return doGet(url, null, null);
    }

    public static String doPost(String url, Map<String, Object> headers, Map<String, Object> params) {
        Assert.hasLength(url, "请求地址不能为null！");
        // 创建HttpPost对象，相当于设置url请求地址
        HttpPost post = new HttpPost(url);
        // 判断请求头是否为空
        if (CollectionUtils.isNotEmpty(headers)) {
            for (Map.Entry<String, Object> entry : headers.entrySet()) {
                // 添加请求头
                post.addHeader(entry.getKey(), (String) entry.getValue());
            }
        }
        // 判断参数是否为空
        if (CollectionUtils.isNotEmpty(params)) {
            StringEntity stringEntity = new StringEntity(JsonUtils.objectCovertToJson(params), "utf-8");
            // 设置请求参数
            post.setEntity(stringEntity);
        }
        return executeHttp(post);
    }

    /**
     * 不带参数的POST请求
     * @param url 请求地址
     * @return 返回请求结果
     */
    public static String doPost(String url) {
        return doPost(url, null, null);
    }

    /**
     * 返回常用请求头
     * @return 返回常用请求头
     */
    public static Map<String, String> commentHeader() {
        Map<String, String> map = new HashMap<>(1);
        map.put("Content-Type", "application/json; charset=utf-8");
        return map;
    }

    /**
     * 执行请求，并且获取响应
     * @param uriRequest 请求对象
     * @return 返回响应结果
     */
    private static String executeHttp(HttpUriRequest uriRequest) {
        try (CloseableHttpResponse response = HTTP_CLIENT.execute(uriRequest)) {
            // 如果成功获取响应, 则获取响应内容
            if (response.getEntity() != null) {
                return EntityUtils.toString(response.getEntity(), "UTF-8");
            }
        } catch (IOException e) {
            log.error("请求发起失败,原因: ", e);
        }
        return null;
    }

}
